In [2]:
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import h3
import geopandas as gpd
import folium
from shapely.geometry import Polygon
from branca.colormap import linear

import glob
import warnings

pd.set_option('display.max_columns', None)
warnings.filterwarnings("ignore")
In [3]:
csv_files = glob.glob("sample_dataset/*.csv")
csv_files
Out[3]:
['sample_dataset/sample_dataset_demographics.csv',
 'sample_dataset/sample_dataset_location.csv',
 'sample_dataset/sample_dataset_population.csv',
 'sample_dataset/us_zip_codes.csv',
 'sample_dataset/sample_dataset_status.csv',
 'sample_dataset/sample_dataset_services.csv']
In [4]:
demographics_df = pd.read_csv("sample_dataset/sample_dataset_demographics.csv")
location_df = pd.read_csv("sample_dataset/sample_dataset_location.csv")
population_df = pd.read_csv("sample_dataset/sample_dataset_population.csv")
status_df = pd.read_csv("sample_dataset/sample_dataset_status.csv")
services_df = pd.read_csv("sample_dataset/sample_dataset_services.csv")
In [5]:
population_df['Population'] = pd.to_numeric(population_df['Population'], errors='coerce') 
In [6]:
population_df.dtypes
Out[6]:
Zip Code        int64
Population    float64
dtype: object

1. Merging the various individual dataframes into a single dataframe¶

In [8]:
customer_df = demographics_df.merge(services_df, on='Customer ID', how='left')\
                             .merge(location_df, on='Customer ID', how='left')\
                             .merge(status_df, on='Customer ID', how='left') 
In [9]:
customer_df.head()
Out[9]:
Customer ID Gender Age Married Dependents Number of Dependents Referred a Friend Number of Referrals Tenure in Months Offer Home Phone Service Avg Monthly Long Distance Charges Multiple Lines Internet Service Internet Type Avg Monthly GB Download Online Security Online Backup Device Protection Plan Premium Tech Support Streaming TV Streaming Movies Streaming Music Unlimited Data Contract Paperless Billing Payment Method Monthly Charge Total Charges Total Refunds Total Extra Data Charges Total Long Distance Charges Total Revenue State City Zip Code Latitude Longitude Satisfaction Score Customer Status Churn Value Churn Category Churn Reason
0 1608-GMEWB Male 76 No No 0 No 0 45 Offer B Yes 15.65 Yes Yes Fiber Optic 18 No No No No Yes Yes No Yes Two Year Yes Bank Withdrawal 93.9 4200.25 0.0 0 704.25 4904.50 California Stockton 95215 37.946282 -121.139499 4 Stayed 0 NaN NaN
1 2817-LVCPP Female 36 No No 0 No 0 50 NaN Yes 12.62 No No NaN 0 No No No No No No No No Two Year No Credit Card 19.4 1023.95 0.0 0 631.00 1654.95 California Sacramento 95822 38.512569 -121.495184 5 Stayed 0 NaN NaN
2 0997-YTLNY Female 59 No Yes 2 No 0 19 Offer D Yes 4.03 No Yes Cable 26 No No No Yes No No No Yes Month-to-Month No Credit Card 48.8 953.65 0.0 0 76.57 1030.22 California Escondido 92029 33.079834 -117.134275 3 Stayed 0 NaN NaN
3 0526-SXDJP Male 36 Yes No 0 Yes 7 72 Offer A No 0.00 No Yes Cable 17 Yes Yes Yes No No No No Yes Two Year No Bank Withdrawal 42.1 2962.00 0.0 0 0.00 2962.00 California Bell 90201 33.970343 -118.171368 4 Stayed 0 NaN NaN
4 3466-RITXD Male 34 No No 0 No 0 26 NaN Yes 37.59 Yes Yes Fiber Optic 8 Yes Yes No No Yes No No Yes Month-to-Month Yes Credit Card 92.4 2349.80 0.0 0 977.34 3327.14 California Twin Bridges 95735 38.805481 -120.132870 3 Stayed 0 NaN NaN

2. Compute market share per zip code using the population and subscriber count¶

In [11]:
customer_df['Customer Status'].value_counts()
Out[11]:
Customer Status
Stayed     4720
Churned    1869
Joined      454
Name: count, dtype: int64
In [12]:
current_customers = customer_df[customer_df['Customer Status'] != 'Churned'].groupby('Zip Code')['Customer ID'].count().reset_index(name='Customer Count')
In [13]:
customer_market_share = current_customers.merge(population_df, on='Zip Code', how='left')
In [14]:
customer_total = customer_df[customer_df['Customer Status'] != 'Churned']['Customer ID'].count()
In [15]:
customer_total
Out[15]:
5174
In [16]:
customer_market_share['Market Share (% of Population)'] = customer_market_share['Customer Count'] / customer_market_share['Population'] * 100
In [17]:
customer_market_share['Customer Share (% of Total Customers)'] = customer_market_share['Customer Count'] / customer_total * 100
In [18]:
market_share_df = customer_market_share[['Zip Code', 'Market Share (% of Population)', 'Customer Share (% of Total Customers)']].reset_index(drop=True)
In [19]:
market_share_df['Market Share (% of Population)'] = market_share_df['Market Share (% of Population)'].fillna(0)
market_share_df['Customer Share (% of Total Customers)'] = market_share_df['Customer Share (% of Total Customers)'].fillna(0)
In [20]:
market_share_df.sort_values(by='Market Share (% of Population)', ascending=False).head()
Out[20]:
Zip Code Market Share (% of Population) Customer Share (% of Total Customers)
82 90263 36.363636 0.077310
1406 95735 16.000000 0.077310
1130 95225 14.814815 0.077310
1497 95978 14.285714 0.077310
59 90071 14.285714 0.057982

3. Analyze churn and market share as a function of metrics such as age, average monthly GB download¶

In [22]:
customer_df = customer_df.merge(market_share_df, on='Zip Code', how='left')
In [23]:
customer_df['Market Share (% of Population)'] = customer_df['Market Share (% of Population)'].fillna(0)
customer_df['Customer Share (% of Total Customers)'] = customer_df['Customer Share (% of Total Customers)'].fillna(0)
In [24]:
# Visualize the relationship between continuous features and the Churn Value
In [25]:
# List of features to plot 
features = ['Age', 'Number of Dependents', 'Number of Referrals',
       'Tenure in Months', 'Avg Monthly Long Distance Charges',
       'Avg Monthly GB Download', 'Monthly Charge', 'Total Charges',
       'Total Refunds', 'Total Extra Data Charges',
       'Total Long Distance Charges', 'Total Revenue', 'Satisfaction Score', 'Market Share (% of Population)']

# Number of rows and columns in the grid
n_rows = 4 
n_cols = 4

# Create a grid of subplots
fig, axes = plt.subplots(n_rows, n_cols, figsize=(5 * n_cols, 4 * n_rows))

axes = axes.flatten()

for i, feature in enumerate(features):
    ax = axes[i]  
    sns.kdeplot(data=customer_df, x=feature, hue='Churn Value', fill=True, ax=ax)
    ax.set_xlabel(feature)

plt.tight_layout()
plt.show()
No description has been provided for this image
In [26]:
# Visualize the relationship between continuous features and the Market Share
In [27]:
plt.figure(figsize=(10, 3))
sns.histplot(customer_df['Market Share (% of Population)'], bins=100, kde=True)
plt.title("Market Share Distribution")
plt.xlabel("Market Share %")
plt.ylabel("Zip Count")
plt.tight_layout()
plt.show()
No description has been provided for this image
In [28]:
market_share = customer_df['Market Share (% of Population)']

bins_log = [0, 1, 10, 50, 100]
labels_log = ['0 - 1%', '1 - 10%', '10 - 50%', '50 - 100%']

# Use pd.cut to bin the market share into 4 bins with the custom labels
market_share_binned = pd.cut(market_share, bins=bins_log, labels=labels_log)

customer_df['Market Share Bin'] = market_share_binned
In [29]:
customer_df['Market Share Bin'].value_counts()
Out[29]:
Market Share Bin
0 - 1%       704
1 - 10%      448
10 - 50%      35
50 - 100%      0
Name: count, dtype: int64
In [30]:
# List of features to plot 
features = ['Age', 'Number of Dependents', 'Number of Referrals',
       'Tenure in Months', 'Avg Monthly Long Distance Charges',
       'Avg Monthly GB Download', 'Monthly Charge', 'Total Charges',
       'Total Refunds', 'Total Extra Data Charges',
       'Total Long Distance Charges', 'Total Revenue', 'Satisfaction Score', 'Churn Value']

# Number of rows and columns in the grid
n_rows = 4 
n_cols = 4

# Create a grid of subplots
fig, axes = plt.subplots(n_rows, n_cols, figsize=(5 * n_cols, 4 * n_rows))

axes = axes.flatten()

for i, feature in enumerate(features):
    ax = axes[i]  
    sns.kdeplot(data=customer_df, x=feature, hue='Market Share Bin', fill=True, ax=ax)
    ax.set_xlabel(feature)

plt.tight_layout()
plt.show()
No description has been provided for this image

4. Create spatial plots of churn rate and market share¶

In [32]:
customer_df
Out[32]:
Customer ID Gender Age Married Dependents Number of Dependents Referred a Friend Number of Referrals Tenure in Months Offer Home Phone Service Avg Monthly Long Distance Charges Multiple Lines Internet Service Internet Type Avg Monthly GB Download Online Security Online Backup Device Protection Plan Premium Tech Support Streaming TV Streaming Movies Streaming Music Unlimited Data Contract Paperless Billing Payment Method Monthly Charge Total Charges Total Refunds Total Extra Data Charges Total Long Distance Charges Total Revenue State City Zip Code Latitude Longitude Satisfaction Score Customer Status Churn Value Churn Category Churn Reason Market Share (% of Population) Customer Share (% of Total Customers) Market Share Bin
0 1608-GMEWB Male 76 No No 0 No 0 45 Offer B Yes 15.65 Yes Yes Fiber Optic 18 No No No No Yes Yes No Yes Two Year Yes Bank Withdrawal 93.90 4200.25 0.0 0 704.25 4904.50 California Stockton 95215 37.946282 -121.139499 4 Stayed 0 NaN NaN 0.0 0.077310 NaN
1 2817-LVCPP Female 36 No No 0 No 0 50 NaN Yes 12.62 No No NaN 0 No No No No No No No No Two Year No Credit Card 19.40 1023.95 0.0 0 631.00 1654.95 California Sacramento 95822 38.512569 -121.495184 5 Stayed 0 NaN NaN 0.0 0.077310 NaN
2 0997-YTLNY Female 59 No Yes 2 No 0 19 Offer D Yes 4.03 No Yes Cable 26 No No No Yes No No No Yes Month-to-Month No Credit Card 48.80 953.65 0.0 0 76.57 1030.22 California Escondido 92029 33.079834 -117.134275 3 Stayed 0 NaN NaN 0.0 0.057982 NaN
3 0526-SXDJP Male 36 Yes No 0 Yes 7 72 Offer A No 0.00 No Yes Cable 17 Yes Yes Yes No No No No Yes Two Year No Bank Withdrawal 42.10 2962.00 0.0 0 0.00 2962.00 California Bell 90201 33.970343 -118.171368 4 Stayed 0 NaN NaN 0.0 0.096637 NaN
4 3466-RITXD Male 34 No No 0 No 0 26 NaN Yes 37.59 Yes Yes Fiber Optic 8 Yes Yes No No Yes No No Yes Month-to-Month Yes Credit Card 92.40 2349.80 0.0 0 977.34 3327.14 California Twin Bridges 95735 38.805481 -120.132870 3 Stayed 0 NaN NaN 16.0 0.077310 10 - 50%
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
7038 3500-NSDOA Male 35 Yes No 0 Yes 1 68 NaN Yes 11.12 Yes Yes Cable 10 No Yes No Yes No Yes Yes Yes Two Year No Credit Card 70.80 4859.95 0.0 0 756.16 5616.11 California Los Angeles 90008 34.008293 -118.346766 4 Stayed 0 NaN NaN 0.0 0.096637 NaN
7039 4654-ULTTN Male 34 Yes No 0 Yes 9 70 Offer A Yes 8.28 Yes Yes DSL 5 Yes No Yes Yes No Yes Yes Yes Two Year Yes Credit Card 74.80 5315.80 0.0 0 579.60 5895.40 California Fillmore 93015 34.408161 -118.865111 3 Stayed 0 NaN NaN 0.0 0.077310 NaN
7040 1506-YJTYT Male 21 Yes Yes 1 Yes 9 45 Offer B Yes 25.69 Yes Yes DSL 26 Yes Yes No Yes Yes No No Yes Two Year No Credit Card 73.85 3371.00 0.0 0 1156.05 4527.05 California Oakley 94561 37.999406 -121.686241 3 Stayed 0 NaN NaN 0.0 0.057982 NaN
7041 1173-NOEYG Female 25 Yes No 0 Yes 1 27 NaN Yes 18.74 Yes Yes Fiber Optic 59 No No Yes No No Yes Yes Yes Month-to-Month No Bank Withdrawal 90.15 2423.40 0.0 0 505.98 2929.38 California Santa Margarita 93453 35.303926 -120.256567 4 Stayed 0 NaN NaN 0.0 0.077310 NaN
7042 9101-BWFSS Female 58 Yes No 0 Yes 1 50 Offer B Yes 29.43 Yes Yes Fiber Optic 14 Yes Yes No Yes Yes Yes Yes Yes One Year No Bank Withdrawal 108.55 5610.70 0.0 0 1471.50 7082.20 California Tollhouse 93667 36.993666 -119.348267 2 Churned 1 Other Moved 0.0 0.057982 NaN

7043 rows × 46 columns

In [33]:
customer_df['Zip Code'].nunique()
Out[33]:
1625
In [34]:
def get_h3_index(lat, lon, resolution=4):
    try:
        return h3.geo_to_h3(lat, lon, resolution)
    except Exception as e:
        print(f"Error converting lat/lon to H3: {e}")
        return None  # Return None if there's an issue
In [35]:
customer_df['H3 Index'] = customer_df.apply(
    lambda row: get_h3_index(row['Latitude'], row['Longitude']), axis=1
)
In [36]:
us_zip_codes_df = customer_df[['Zip Code', 'H3 Index']].drop_duplicates().reset_index(drop=True)
In [37]:
us_zip_codes_df
Out[37]:
Zip Code H3 Index
0 95215 8428363ffffffff
1 95822 842832bffffffff
2 92029 8429a47ffffffff
3 90201 8429a57ffffffff
4 95735 84298d3ffffffff
... ... ...
1621 94074 8428343ffffffff
1622 91934 8448593ffffffff
1623 94021 8428341ffffffff
1624 95677 8428321ffffffff
1625 94122 8428309ffffffff

1626 rows × 2 columns

In [38]:
churn_by_zip_code = customer_df.groupby('Zip Code').agg(
    total_customers=('Churn Value', 'count'),
    churned_customers=('Churn Value', 'sum')  # Sum gives count of churned customers
).reset_index()
In [39]:
churn_by_zip_code['Churn Rate (%)'] = (churn_by_zip_code['churned_customers'] / churn_by_zip_code['total_customers']) * 100
In [40]:
churn_by_zip_code.head()
Out[40]:
Zip Code total_customers churned_customers Churn Rate (%)
0 90001 4 1 25.0
1 90002 4 0 0.0
2 90003 5 1 20.0
3 90004 5 2 40.0
4 90005 4 2 50.0
In [41]:
churn_by_zip_code.drop(columns=['churned_customers', 'total_customers'], inplace=True)
In [42]:
market_churn_df = us_zip_codes_df.merge(market_share_df, on='Zip Code', how='left')\
               .merge(churn_by_zip_code, on='Zip Code', how='left')
In [43]:
market_churn_df['Churn Rate (%)'] = market_churn_df['Churn Rate (%)'].fillna(0)
market_churn_df['Market Share (% of Population)'] = market_churn_df['Market Share (% of Population)'].fillna(0)
market_churn_df['Customer Share (% of Total Customers)'] = market_churn_df['Customer Share (% of Total Customers)'].fillna(0)
In [44]:
market_churn_df.sort_values(by='Market Share (% of Population)', ascending=False).head()
Out[44]:
Zip Code H3 Index Market Share (% of Population) Customer Share (% of Total Customers) Churn Rate (%)
74 90263 8429a19ffffffff 36.363636 0.077310 20.0
4 95735 84298d3ffffffff 16.000000 0.077310 0.0
652 95225 8428367ffffffff 14.814815 0.077310 0.0
551 95978 842814bffffffff 14.285714 0.077310 0.0
1092 90071 8429a1dffffffff 14.285714 0.057982 40.0
In [45]:
market_churn_df.to_csv('customer_churn_data.csv', index=False)
In [46]:
# Function to convert H3 index to a Shapely Polygon
def h3_to_polygon(h3_index):
    """Convert an H3 index to a Shapely Polygon"""
    boundary = h3.h3_to_geo_boundary(h3_index)  # Returns list of (lat, lon) tuples
    return Polygon([(lon, lat) for lat, lon in boundary])  # Convert to (lon, lat) for Shapely

# Convert H3 indices to polygons and create a GeoDataFrame
df = market_churn_df.copy()
df['geometry'] = df['H3 Index'].apply(h3_to_polygon)
gdf = gpd.GeoDataFrame(df, geometry='geometry')

# Compute centroid dynamically for better positioning
centroid = gdf.geometry.unary_union.centroid

# Create base map
leaflet_map = folium.Map(location=[centroid.y, centroid.x], zoom_start=6, tiles="CartoDB Positron")

# Define colormaps
churn_colormap = linear.Reds_09.scale(df['Churn Rate (%)'].min(), df['Churn Rate (%)'].max())
market_share_colormap = linear.Greens_09.scale(df['Market Share (% of Population)'].min(), df['Market Share (% of Population)'].max())

# Add Churn Rate Layer
churn_layer = folium.FeatureGroup(name="Churn Rate (%)", show=True)
for _, row in gdf.iterrows():
    folium.GeoJson(
        row['geometry'],
        style_function=lambda x, rate=row['Churn Rate (%)']: {
            'fillColor': churn_colormap(rate),
            'color': '#222222',
            'weight': 1,
            'fillOpacity': 0.75
        },
        tooltip=folium.Tooltip(f"<b>Churn Rate:</b> {row['Churn Rate (%)']:.2f}%<br><b>Market Share:</b> {row['Market Share (% of Population)']:.2f}%")
    ).add_to(churn_layer)
churn_layer.add_to(leaflet_map)

# Add Market Share Layer
market_layer = folium.FeatureGroup(name="Market Share (%)", show=False)
for _, row in gdf.iterrows():
    folium.GeoJson(
        row['geometry'],
        style_function=lambda x, rate=row['Market Share (% of Population)']: {
            'fillColor': market_share_colormap(rate),
            'color': '#222222',
            'weight': 1,
            'fillOpacity': 0.75
        },
        tooltip=folium.Tooltip(f"<b>Churn Rate:</b> {row['Churn Rate (%)']:.2f}%<br><b>Market Share:</b> {row['Market Share (% of Population)']:.2f}%")
    ).add_to(market_layer)
market_layer.add_to(leaflet_map)

# Add colormaps as legends
churn_colormap.caption = "Churn Rate (%)"
churn_colormap.add_to(leaflet_map)

market_share_colormap.caption = "Market Share (%)"
market_share_colormap.add_to(leaflet_map)

# Add Layer Control to switch between layers
folium.LayerControl(collapsed=False).add_to(leaflet_map)

# Save map as HTML
leaflet_map.save('churn_market_share_map.html')

leaflet_map
Out[46]:
Make this Notebook Trusted to load map: File -> Trust Notebook

5. Generate a customer churn risk value based on the available columns¶

In [48]:
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix, roc_auc_score
In [49]:
customer_df.dtypes
Out[49]:
Customer ID                                object
Gender                                     object
Age                                         int64
Married                                    object
Dependents                                 object
Number of Dependents                        int64
Referred a Friend                          object
Number of Referrals                         int64
Tenure in Months                            int64
Offer                                      object
Home Phone Service                         object
Avg Monthly Long Distance Charges         float64
Multiple Lines                             object
Internet Service                           object
Internet Type                              object
Avg Monthly GB Download                     int64
Online Security                            object
Online Backup                              object
Device Protection Plan                     object
Premium Tech Support                       object
Streaming TV                               object
Streaming Movies                           object
Streaming Music                            object
Unlimited Data                             object
Contract                                   object
Paperless Billing                          object
Payment Method                             object
Monthly Charge                            float64
Total Charges                             float64
Total Refunds                             float64
Total Extra Data Charges                    int64
Total Long Distance Charges               float64
Total Revenue                             float64
State                                      object
City                                       object
Zip Code                                    int64
Latitude                                  float64
Longitude                                 float64
Satisfaction Score                          int64
Customer Status                            object
Churn Value                                 int64
Churn Category                             object
Churn Reason                               object
Market Share (% of Population)            float64
Customer Share (% of Total Customers)     float64
Market Share Bin                         category
H3 Index                                   object
dtype: object
In [50]:
# drop columns to reduce noise and data lekage 
churn_df = customer_df.drop(columns=[ 'Customer ID','Customer Status', 'Churn Category', 'Churn Reason', 'Latitude', 'Longitude', 'Market Share Bin', 'H3 Index'])
In [51]:
numerical_cols = churn_df.select_dtypes(include=[np.number]).columns
print("Continuous Columns:", numerical_cols)
Continuous Columns: Index(['Age', 'Number of Dependents', 'Number of Referrals',
       'Tenure in Months', 'Avg Monthly Long Distance Charges',
       'Avg Monthly GB Download', 'Monthly Charge', 'Total Charges',
       'Total Refunds', 'Total Extra Data Charges',
       'Total Long Distance Charges', 'Total Revenue', 'Zip Code',
       'Satisfaction Score', 'Churn Value', 'Market Share (% of Population)',
       'Customer Share (% of Total Customers)'],
      dtype='object')
In [52]:
categorical_cols = churn_df.select_dtypes(include=['object', 'category', 'bool']).columns
print("Categorical Columns:", categorical_cols)
Categorical Columns: Index(['Gender', 'Married', 'Dependents', 'Referred a Friend', 'Offer',
       'Home Phone Service', 'Multiple Lines', 'Internet Service',
       'Internet Type', 'Online Security', 'Online Backup',
       'Device Protection Plan', 'Premium Tech Support', 'Streaming TV',
       'Streaming Movies', 'Streaming Music', 'Unlimited Data', 'Contract',
       'Paperless Billing', 'Payment Method', 'State', 'City'],
      dtype='object')
In [53]:
churn_df['Churn Value'].value_counts()/len(churn_df) * 100
Out[53]:
Churn Value
0    73.463013
1    26.536987
Name: count, dtype: float64
In [54]:
churn_df.describe()
Out[54]:
Age Number of Dependents Number of Referrals Tenure in Months Avg Monthly Long Distance Charges Avg Monthly GB Download Monthly Charge Total Charges Total Refunds Total Extra Data Charges Total Long Distance Charges Total Revenue Zip Code Satisfaction Score Churn Value Market Share (% of Population) Customer Share (% of Total Customers)
count 7043.000000 7043.000000 7043.000000 7043.000000 7043.000000 7043.000000 7043.000000 7043.000000 7043.000000 7043.000000 7043.000000 7043.000000 7043.000000 7043.000000 7043.000000 7043.000000 7043.000000
mean 46.509726 0.468692 1.951867 32.386767 22.958954 20.515405 64.761692 2280.381264 1.962182 6.860713 749.099262 3034.379056 93486.071134 3.244924 0.265370 0.303195 0.066261
std 16.750352 0.962802 3.001199 24.542061 15.448113 20.418940 30.090047 2266.220462 7.902614 25.104978 846.660055 2865.204542 1856.768045 1.201657 0.441561 1.513353 0.040936
min 19.000000 0.000000 0.000000 1.000000 0.000000 0.000000 18.250000 18.800000 0.000000 0.000000 0.000000 21.360000 90001.000000 1.000000 0.000000 0.000000 0.000000
25% 32.000000 0.000000 0.000000 9.000000 9.210000 3.000000 35.500000 400.150000 0.000000 0.000000 70.545000 605.610000 92101.000000 3.000000 0.000000 0.000000 0.057982
50% 46.000000 0.000000 0.000000 29.000000 22.890000 17.000000 70.350000 1394.550000 0.000000 0.000000 401.440000 2108.640000 93518.000000 3.000000 0.000000 0.000000 0.057982
75% 60.000000 0.000000 3.000000 55.000000 36.395000 27.000000 89.850000 3786.600000 0.000000 0.000000 1191.100000 4801.145000 95329.000000 4.000000 1.000000 0.000000 0.077310
max 80.000000 9.000000 11.000000 72.000000 49.990000 85.000000 118.750000 8684.800000 49.790000 150.000000 3564.720000 11979.340000 96150.000000 5.000000 1.000000 36.363636 0.444530
In [55]:
sns.heatmap(churn_df.corr(numeric_only=True))
Out[55]:
<Axes: >
No description has been provided for this image
In [56]:
# data pre processing 
In [57]:
# Encode categorical variables
churn_df = pd.get_dummies(churn_df, drop_first=True)
In [58]:
churn_df
Out[58]:
Age Number of Dependents Number of Referrals Tenure in Months Avg Monthly Long Distance Charges Avg Monthly GB Download Monthly Charge Total Charges Total Refunds Total Extra Data Charges Total Long Distance Charges Total Revenue Zip Code Satisfaction Score Churn Value Market Share (% of Population) Customer Share (% of Total Customers) Gender_Male Married_Yes Dependents_Yes Referred a Friend_Yes Offer_Offer B Offer_Offer C Offer_Offer D Offer_Offer E Home Phone Service_Yes Multiple Lines_Yes Internet Service_Yes Internet Type_DSL Internet Type_Fiber Optic Online Security_Yes Online Backup_Yes Device Protection Plan_Yes Premium Tech Support_Yes Streaming TV_Yes Streaming Movies_Yes Streaming Music_Yes Unlimited Data_Yes Contract_One Year Contract_Two Year Paperless Billing_Yes Payment Method_Credit Card Payment Method_Mailed Check City_Acton City_Adelanto City_Adin City_Agoura Hills City_Aguanga City_Ahwahnee City_Alameda City_Alamo City_Albany City_Albion City_Alderpoint City_Alhambra City_Aliso Viejo City_Alleghany City_Alpaugh City_Alpine City_Alta City_Altadena City_Alturas City_Alviso City_Amador City City_Amboy City_Anaheim City_Anderson City_Angels Camp City_Angelus Oaks City_Angwin City_Annapolis City_Antelope City_Antioch City_Anza City_Apple Valley City_Applegate City_Aptos City_Arbuckle City_Arcadia City_Arcata City_Armona City_Arnold City_Aromas City_Arroyo Grande City_Artesia City_Arvin City_Atascadero City_Atherton City_Atwater City_Auberry City_Auburn City_Avalon City_Avenal City_Avery City_Avila Beach City_Azusa City_Badger City_Baker City_Bakersfield City_Baldwin Park City_Ballico City_Bangor City_Banning City_Barstow City_Bass Lake City_Bayside City_Beale Afb City_Beaumont City_Bell City_Bella Vista City_Bellflower City_Belmont City_Belvedere Tiburon City_Ben Lomond City_Benicia City_Benton City_Berkeley City_Berry Creek City_Bethel Island City_Beverly Hills City_Bieber City_Big Bar City_Big Bear City City_Big Bear Lake City_Big Bend City_Big Creek City_Big Oak Flat City_Big Pine City_Biggs City_Biola City_Birds Landing City_Bishop City_Blairsden Graeagle City_Blocksburg City_Bloomington City_Blue Lake City_Blythe City_Bodega City_Bodega Bay City_Bodfish City_Bolinas City_Bonita City_Bonsall City_Boonville City_Boron City_Borrego Springs City_Boulder Creek City_Boulevard City_Bradley City_Branscomb City_Brawley City_Brea City_Brentwood City_Bridgeport City_Bridgeville City_Brisbane City_Brookdale City_Brooks City_Browns Valley City_Brownsville City_Buellton City_Buena Park City_Burbank City_Burlingame City_Burney City_Burnt Ranch City_Burson City_Butte City City_Buttonwillow City_Byron City_Cabazon City_Calabasas City_Calexico City_Caliente City_California City City_California Hot Springs City_Calimesa City_Calipatria City_Calistoga City_Callahan City_Calpine City_Camarillo City_Cambria City_Camino City_Camp Nelson City_Campbell City_Campo City_Campo Seco City_Camptonville City_Canby City_Canoga Park City_Cantua Creek City_Canyon Country City_Canyon Dam City_Capay City_Capistrano Beach City_Capitola City_Cardiff By The Sea City_Carlotta City_Carlsbad City_Carmel City_Carmel By The Sea City_Carmel Valley City_Carmichael City_Carnelian Bay City_Carpinteria City_Carson City_Caruthers City_Casmalia City_Caspar City_Cassel City_Castaic City_Castella City_Castro Valley City_Castroville City_Cathedral City City_Catheys Valley City_Cayucos City_Cazadero City_Cedar Glen City_Cedarville City_Ceres City_Cerritos City_Challenge City_Chatsworth City_Chester City_Chico City_Chilcoot City_Chino City_Chino Hills City_Chowchilla City_Chualar City_Chula Vista City_Citrus Heights City_Claremont City_Clarksburg City_Clayton City_Clearlake City_Clearlake Oaks City_Clements City_Clio City_Clipper Mills City_Cloverdale City_Clovis City_Coachella City_Coalinga City_Coarsegold City_Cobb City_Coleville City_Colfax City_Colton City_Columbia City_Colusa City_Comptche City_Compton City_Concord City_Cool City_Copperopolis City_Corcoran City_Corning City_Corona City_Corona Del Mar City_Coronado City_Corte Madera City_Costa Mesa City_Cotati City_Cottonwood City_Coulterville City_Courtland City_Covelo City_Covina City_Crescent Mills City_Cressey City_Crestline City_Creston City_Crockett City_Crows Landing City_Culver City City_Cupertino City_Cutler City_Cypress City_Daggett City_Daly City City_Dana Point City_Danville City_Darwin City_Davenport City_Davis City_Davis Creek City_Death Valley City_Deer Park City_Del Mar City_Del Rey City_Delano City_Delhi City_Denair City_Descanso City_Desert Center City_Desert Hot Springs City_Diamond Bar City_Diamond Springs City_Dillon Beach City_Dinuba City_Dixon City_Dobbins City_Dorris City_Dos Palos City_Dos Rios City_Douglas City City_Downey City_Downieville City_Doyle City_Duarte City_Dublin City_Ducor City_Dulzura City_Duncans Mills City_Dunlap City_Dunnigan City_Dunsmuir City_Durham City_Dutch Flat City_Eagleville City_Earlimart City_Earp City_Echo Lake City_Edwards City_El Cajon City_El Centro City_El Cerrito City_El Dorado City_El Dorado Hills City_El Monte City_El Nido City_El Portal City_El Segundo City_El Sobrante City_Eldridge City_Elk City_Elk Creek City_Elk Grove City_Elmira City_Elverta City_Emeryville City_Emigrant Gap City_Encinitas City_Encino City_Escalon City_Escondido City_Esparto City_Essex City_Etna City_Eureka City_Exeter City_Fair Oaks City_Fairfax City_Fairfield City_Fall River Mills City_Fallbrook City_Farmersville City_Farmington City_Fawnskin City_Fellows City_Felton City_Ferndale City_Fiddletown City_Fields Landing City_Fillmore City_Firebaugh City_Fish Camp City_Five Points City_Flournoy City_Folsom City_Fontana City_Foothill Ranch City_Forbestown City_Forest Falls City_Forest Knolls City_Forest Ranch City_Foresthill City_Forestville City_Forks Of Salmon City_Fort Bidwell City_Fort Bragg City_Fort Irwin City_Fortuna City_Fountain Valley City_Fowler City_Frazier Park City_Freedom City_Fremont City_French Camp City_French Gulch City_Fresno City_Friant City_Fullerton City_Fulton City_Galt City_Garberville City_Garden Grove City_Garden Valley City_Gardena City_Gasquet City_Gazelle City_Georgetown City_Gerber City_Geyserville City_Gilroy City_Glen Ellen City_Glencoe City_Glendale City_Glendora City_Glenhaven City_Glenn City_Glennville City_Gold Run City_Goleta City_Gonzales City_Goodyears Bar City_Granada Hills City_Grand Terrace City_Granite Bay City_Grass Valley City_Graton City_Green Valley Lake City_Greenbrae City_Greenfield City_Greenview City_Greenville City_Greenwood City_Grenada City_Gridley City_Grimes City_Grizzly Flats City_Groveland City_Grover Beach City_Guadalupe City_Gualala City_Guatay City_Guerneville City_Guinda City_Gustine City_Hacienda Heights City_Half Moon Bay City_Hamilton City City_Hanford City_Happy Camp City_Harbor City City_Hat Creek City_Hathaway Pines City_Hawaiian Gardens City_Hawthorne City_Hayward City_Healdsburg City_Heber City_Helendale City_Helm City_Hemet City_Herald City_Hercules City_Herlong City_Hermosa Beach City_Hesperia City_Hickman City_Highland City_Hilmar City_Hinkley City_Holtville City_Homeland City_Homewood City_Honeydew City_Hood City_Hoopa City_Hopland City_Hornbrook City_Hornitos City_Hughson City_Hume City_Huntington Beach City_Huntington Park City_Huron City_Hyampom City_Hydesville City_Idyllwild City_Igo City_Imperial City_Imperial Beach City_Independence City_Indian Wells City_Indio City_Inglewood City_Inverness City_Ione City_Irvine City_Isleton City_Ivanhoe City_Jackson City_Jacumba City_Jamestown City_Jamul City_Janesville City_Jenner City_Johannesburg City_Jolon City_Joshua Tree City_Julian City_Junction City City_June Lake City_Keeler City_Keene City_Kelseyville City_Kenwood City_Kerman City_Kernville City_Kettleman City City_Keyes City_King City City_Kings Beach City_Kingsburg City_Kirkwood City_Klamath City_Klamath River City_Kneeland City_Knights Landing City_Korbel City_Kyburz City_La Canada Flintridge City_La Crescenta City_La Grange City_La Habra City_La Honda City_La Jolla City_La Mesa City_La Mirada City_La Palma City_La Puente City_La Quinta City_La Verne City_Ladera Ranch City_Lafayette City_Laguna Beach City_Laguna Hills City_Laguna Niguel City_Lagunitas City_Lake Arrowhead City_Lake Elsinore City_Lake Forest City_Lake Hughes City_Lake Isabella City_Lakehead City_Lakeport City_Lakeshore City_Lakeside City_Lakewood City_Lamont City_Lancaster City_Landers City_Larkspur City_Lathrop City_Laton City_Lawndale City_Laytonville City_Le Grand City_Lebec City_Lee Vining City_Leggett City_Lemon Cove City_Lemon Grove City_Lemoore City_Lewiston City_Likely City_Lincoln City_Linden City_Lindsay City_Litchfield City_Little River City_Littlerock City_Live Oak City_Livermore City_Livingston City_Llano City_Lockeford City_Lockwood City_Lodi City_Loleta City_Loma Linda City_Loma Mar City_Lomita City_Lompoc City_Long Barn City_Long Beach City_Lookout City_Loomis City_Los Alamitos City_Los Alamos City_Los Altos City_Los Angeles City_Los Banos City_Los Gatos City_Los Molinos City_Los Olivos City_Los Osos City_Lost Hills City_Lotus City_Lower Lake City_Loyalton City_Lucerne City_Lucerne Valley City_Ludlow City_Lynwood City_Lytle Creek City_Macdoel City_Mad River City_Madeline City_Madera City_Madison City_Magalia City_Malibu City_Mammoth Lakes City_Manchester City_Manhattan Beach City_Manteca City_Manton City_March Air Reserve Base City_Marina City_Marina Del Rey City_Mariposa City_Markleeville City_Marshall City_Martinez City_Marysville City_Mather City_Maxwell City_Maywood City_Mc Farland City_Mc Kittrick City_Mcarthur City_Mccloud City_Mckinleyville City_Meadow Valley City_Meadow Vista City_Mecca City_Mendocino City_Menifee City_Menlo Park City_Mentone City_Merced City_Meridian City_Mi Wuk Village City_Middletown City_Midpines City_Midway City City_Milford City_Mill Creek City_Mill Valley City_Millbrae City_Millville City_Milpitas City_Mineral City_Mira Loma City_Miramonte City_Miranda City_Mission Hills City_Mission Viejo City_Modesto City_Mojave City_Mokelumne Hill City_Monrovia City_Montara City_Montclair City_Monte Rio City_Montebello City_Monterey City_Monterey Park City_Montgomery Creek City_Montrose City_Moorpark City_Moraga City_Moreno Valley City_Morgan Hill City_Morongo Valley City_Morro Bay City_Moss Beach City_Moss Landing City_Mount Hamilton City_Mount Hermon City_Mount Laguna City_Mount Shasta City_Mountain Center City_Mountain Ranch City_Mountain View City_Mt Baldy City_Murphys City_Murrieta City_Myers Flat City_Napa City_National City City_Navarro City_Needles City_Nevada City City_New Cuyama City_Newark City_Newbury Park City_Newcastle City_Newhall City_Newman City_Newport Beach City_Newport Coast City_Nicasio City_Nice City_Nicolaus City_Niland City_Nipomo City_Nipton City_Norco City_North Fork City_North Highlands City_North Hills City_North Hollywood City_North Palm Springs City_North San Juan City_Northridge City_Norwalk City_Novato City_Nubieber City_Nuevo City_O Neals City_Oak Park City_Oak Run City_Oak View City_Oakdale City_Oakhurst City_Oakland City_Oakley City_Occidental City_Oceano City_Oceanside City_Ocotillo City_Ojai City_Olancha City_Old Station City_Olema City_Olivehurst City_Olympic Valley City_Ontario City_Orange City_Orange Cove City_Orangevale City_Oregon House City_Orick City_Orinda City_Orland City_Orleans City_Oro Grande City_Orosi City_Oroville City_Oxnard City_Pacific Grove City_Pacific Palisades City_Pacifica City_Pacoima City_Paicines City_Pala City_Palermo City_Palm Desert City_Palm Springs City_Palmdale City_Palo Alto City_Palo Cedro City_Palo Verde City_Palomar Mountain City_Palos Verdes Peninsula City_Paradise City_Paramount City_Parker Dam City_Parlier City_Pasadena City_Paskenta City_Paso Robles City_Patterson City_Pauma Valley City_Paynes Creek City_Pearblossom City_Pebble Beach City_Penn Valley City_Penngrove City_Penryn City_Perris City_Pescadero City_Petaluma City_Petrolia City_Phelan City_Phillipsville City_Philo City_Pico Rivera City_Piercy City_Pilot Hill City_Pine Grove City_Pine Valley City_Pinecrest City_Pinole City_Pinon Hills City_Pioneer City_Pioneertown City_Piru City_Pismo Beach City_Pittsburg City_Pixley City_Placentia City_Placerville City_Planada City_Platina City_Playa Del Rey City_Pleasant Grove City_Pleasant Hill City_Pleasanton City_Plymouth City_Point Arena City_Point Reyes Station City_Pollock Pines City_Pomona City_Pope Valley City_Port Costa City_Port Hueneme City_Porter Ranch City_Porterville City_Portola City_Portola Valley City_Posey City_Potrero City_Potter Valley City_Poway City_Prather City_Princeton City_Quincy City_Raisin City City_Ramona City_Ranchita City_Rancho Cordova City_Rancho Cucamonga City_Rancho Mirage City_Rancho Palos Verdes City_Rancho Santa Fe City_Rancho Santa Margarita City_Randsburg City_Ravendale City_Raymond City_Red Bluff City_Redcrest City_Redding City_Redlands City_Redondo Beach City_Redway City_Redwood City City_Redwood Valley City_Reedley City_Rescue City_Reseda City_Rialto City_Richgrove City_Richmond City_Richvale City_Rio Dell City_Rio Linda City_Rio Nido City_Rio Oso City_Rio Vista City_Ripon City_River Pines City_Riverbank City_Riverdale City_Riverside City_Rocklin City_Rodeo City_Rohnert Park City_Rosamond City_Rosemead City_Roseville City_Rough And Ready City_Round Mountain City_Rowland Heights City_Running Springs City_Sacramento City_Saint Helena City_Salida City_Salinas City_Salton City City_Salyer City_Samoa City_San Andreas City_San Anselmo City_San Ardo City_San Bernardino City_San Bruno City_San Carlos City_San Clemente City_San Diego City_San Dimas City_San Fernando City_San Francisco City_San Gabriel City_San Geronimo City_San Gregorio City_San Jacinto City_San Joaquin City_San Jose City_San Juan Bautista City_San Juan Capistrano City_San Leandro City_San Lorenzo City_San Lucas City_San Luis Obispo City_San Marcos City_San Marino City_San Martin City_San Mateo City_San Miguel City_San Pablo City_San Pedro City_San Quentin City_San Rafael City_San Ramon City_San Simeon City_San Ysidro City_Sanger City_Santa Ana City_Santa Barbara City_Santa Clara City_Santa Clarita City_Santa Cruz City_Santa Fe Springs City_Santa Margarita City_Santa Maria City_Santa Monica City_Santa Paula City_Santa Rosa City_Santa Ynez City_Santa Ysabel City_Santee City_Saratoga City_Sausalito City_Scotia City_Scott Bar City_Scotts Valley City_Seal Beach City_Seaside City_Sebastopol City_Seeley City_Seiad Valley City_Selma City_Sequoia National Park City_Shafter City_Shandon City_Shasta City_Shasta Lake City_Shaver Lake City_Sheep Ranch City_Sheridan City_Sherman Oaks City_Shingle Springs City_Shingletown City_Shoshone City_Sierra City City_Sierra Madre City_Sierraville City_Silverado City_Simi Valley City_Sloughhouse City_Smartville City_Smith River City_Snelling City_Soda Springs City_Solana Beach City_Soledad City_Solvang City_Somerset City_Somes Bar City_Somis City_Sonoma City_Sonora City_Soquel City_Soulsbyville City_South Dos Palos City_South El Monte City_South Gate City_South Lake Tahoe City_South Pasadena City_South San Francisco City_Spreckels City_Spring Valley City_Springville City_Squaw Valley City_Standish City_Stanford City_Stanton City_Stevenson Ranch City_Stevinson City_Stinson Beach City_Stirling City City_Stockton City_Stonyford City_Stratford City_Strathmore City_Strawberry Valley City_Studio City City_Sugarloaf City_Suisun City City_Sultana City_Summerland City_Sun City City_Sun Valley City_Sunland City_Sunnyvale City_Sunol City_Sunset Beach City_Surfside City_Susanville City_Sutter City_Sutter Creek City_Sylmar City_Taft City_Tahoe City City_Tahoe Vista City_Tahoma City_Tarzana City_Taylorsville City_Tecate City_Tehachapi City_Tehama City_Temecula City_Temple City City_Templeton City_Termo City_Terra Bella City_The Sea Ranch City_Thermal City_Thornton City_Thousand Oaks City_Thousand Palms City_Three Rivers City_Tollhouse City_Tomales City_Topanga City_Topaz City_Torrance City_Trabuco Canyon City_Tracy City_Tranquillity City_Traver City_Travis Afb City_Trinidad City_Trinity Center City_Tujunga City_Tulare City_Tulelake City_Tuolumne City_Tupman City_Turlock City_Tustin City_Twain City_Twain Harte City_Twentynine Palms City_Twin Bridges City_Ukiah City_Union City City_Upland City_Upper Lake City_Vacaville City_Valencia City_Vallecito City_Vallejo City_Valley Center City_Valley Ford City_Valley Springs City_Valley Village City_Valyermo City_Van Nuys City_Venice City_Ventura City_Vernalis City_Victorville City_Villa Park City_Vina City_Visalia City_Vista City_Volcano City_Wallace City_Walnut City_Walnut Creek City_Walnut Grove City_Warner Springs City_Wasco City_Washington City_Waterford City_Watsonville City_Weaverville City_Weed City_Weimar City_Weldon City_Wendel City_Weott City_West Covina City_West Hills City_West Hollywood City_West Point City_West Sacramento City_Westlake Village City_Westminster City_Westmorland City_Westport City_Westwood City_Wheatland City_White Water City_Whitmore City_Whittier City_Wildomar City_Williams City_Willits City_Willow Creek City_Willows City_Wilmington City_Wilseyville City_Wilton City_Winchester City_Windsor City_Winnetka City_Winterhaven City_Winters City_Winton City_Wishon City_Witter Springs City_Wofford Heights City_Woodacre City_Woodbridge City_Woodlake City_Woodland City_Woodland Hills City_Woody City_Wrightwood City_Yermo City_Yorba Linda City_Yorkville City_Yountville City_Yreka City_Yuba City City_Yucaipa City_Yucca Valley City_Zenia
0 76 0 0 45 15.65 18 93.90 4200.25 0.0 0 704.25 4904.50 95215 4 0 0.0 0.077310 True False False False True False False False True True True False True False False False False True True False True False True True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False
1 36 0 0 50 12.62 0 19.40 1023.95 0.0 0 631.00 1654.95 95822 5 0 0.0 0.077310 False False False False False False False False True False False False False False False False False False False False False False True False True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False
2 59 2 0 19 4.03 26 48.80 953.65 0.0 0 76.57 1030.22 92029 3 0 0.0 0.057982 False False True False False False True False True False True False False False False False True False False False True False False False True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False
3 36 0 7 72 0.00 17 42.10 2962.00 0.0 0 0.00 2962.00 90201 4 0 0.0 0.096637 True True False True False False False False False False True False False True True True False False False False True False True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False
4 34 0 0 26 37.59 8 92.40 2349.80 0.0 0 977.34 3327.14 95735 3 0 16.0 0.077310 True False False False False False False False True True True False True True True False False True False False True False False True True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
7038 35 0 1 68 11.12 10 70.80 4859.95 0.0 0 756.16 5616.11 90008 4 0 0.0 0.096637 True True False True False False False False True True True False False False True False True False True True True False True False True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False
7039 34 0 9 70 8.28 5 74.80 5315.80 0.0 0 579.60 5895.40 93015 3 0 0.0 0.077310 True True False True False False False False True True True True False True False True True False True True True False True True True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False
7040 21 1 9 45 25.69 26 73.85 3371.00 0.0 0 1156.05 4527.05 94561 3 0 0.0 0.057982 True True True True True False False False True True True True False True True False True True False False True False True False True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False
7041 25 0 1 27 18.74 59 90.15 2423.40 0.0 0 505.98 2929.38 93453 4 0 0.0 0.077310 False True False True False False False False True True True False True False False True False False True True True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False
7042 58 0 1 50 29.43 14 108.55 5610.70 0.0 0 1471.50 7082.20 93667 2 1 0.0 0.057982 False True False True True False False False True True True False True True True False True True True True True True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False True False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False False

7043 rows × 1148 columns

In [59]:
# Split data into features (X) and target (y)
X = churn_df.drop('Churn Value', axis=1)
y = churn_df['Churn Value']

# Split into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
In [60]:
train_df = pd.DataFrame(X_train)
train_df['Churn Value'] = y_train
In [61]:
rf_model = RandomForestClassifier(n_estimators=100, random_state=42)
rf_model.fit(X_train, y_train)
Out[61]:
RandomForestClassifier(random_state=42)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
RandomForestClassifier(random_state=42)
In [62]:
from sklearn.model_selection import GridSearchCV

param_grid = {
    'n_estimators': [100, 200, 300], # Number of trees in the forest
    'max_depth': [10, 20, 30], 
    'min_samples_leaf': [1, 2, 4]
}
In [63]:
grid_search = GridSearchCV(estimator=rf_model, param_grid=param_grid, cv=5, n_jobs=-1, verbose=2, scoring='precision')
In [64]:
# Fit GridSearchCV on the training data
grid_search.fit(X_train, y_train)

# Get the best parameters and the best model
best_params = grid_search.best_params_
best_rf_model = grid_search.best_estimator_

print(f"Best Hyperparameters: {best_params}")
Fitting 5 folds for each of 27 candidates, totalling 135 fits
Best Hyperparameters: {'max_depth': 10, 'min_samples_leaf': 4, 'n_estimators': 300}
In [65]:
y_pred = best_rf_model.predict(X_test)

Model Evaluation - Create metrics to understand your model's performance¶

In [67]:
# Random Forest Performance
y_pred_rf = best_rf_model.predict(X_test)
print('Random Forest Performance:')
print(classification_report(y_test, y_pred_rf))
Random Forest Performance:
              precision    recall  f1-score   support

           0       0.83      1.00      0.91      1021
           1       0.99      0.48      0.65       388

    accuracy                           0.86      1409
   macro avg       0.91      0.74      0.78      1409
weighted avg       0.88      0.86      0.84      1409

In [68]:
cm = confusion_matrix(y_test, y_pred)
TN, FP, FN, TP = cm.ravel()
In [69]:
print(f"True Negatives (TN): {TN}")
print(f"False Positives (FP): {FP}")
print(f"False Negatives (FN): {FN}")
print(f"True Positives (TP): {TP}")
True Negatives (TN): 1019
False Positives (FP): 2
False Negatives (FN): 202
True Positives (TP): 186
In [70]:
# Feature Importance from Random Forest
feature_importances = pd.DataFrame(rf_model.feature_importances_, index=X.columns, columns=['importance']).sort_values('importance', ascending=False)
feature_importances.head(10)
Out[70]:
importance
Satisfaction Score 0.259821
Customer Share (% of Total Customers) 0.053492
Tenure in Months 0.046811
Monthly Charge 0.040312
Total Charges 0.037422
Total Revenue 0.036452
Total Long Distance Charges 0.034581
Number of Referrals 0.034178
Contract_Two Year 0.028117
Avg Monthly GB Download 0.027535
In [71]:
import shap
explainer = shap.TreeExplainer(best_rf_model)
shap_values = explainer.shap_values(X_test)
In [72]:
shap_values_class_1 = shap_values[:, :, 1]
In [73]:
shap.summary_plot(shap_values_class_1, X_test)
No description has been provided for this image
In [74]:
# generate customer churn risk value for all customers and save to a file
In [75]:
curn_risk_df = customer_df.drop(columns=[ 'Customer ID','Customer Status', 'Churn Category', 'Churn Value', 'Churn Reason', 'Latitude', 'Longitude', 'Market Share Bin', 'H3 Index'])
curn_risk_df = pd.get_dummies(curn_risk_df, drop_first=True)
In [76]:
y_pred_rf = best_rf_model.predict_proba(curn_risk_df)
In [77]:
customer_df['Churn Risk'] = y_pred_rf[:, 1]
In [78]:
customer_df[['Customer ID', 'Churn Risk']].to_csv('customer_churn_risk_score.csv', index=False)
In [79]:
customer_df[customer_df['Churn Risk'] > 0.5]
Out[79]:
Customer ID Gender Age Married Dependents Number of Dependents Referred a Friend Number of Referrals Tenure in Months Offer Home Phone Service Avg Monthly Long Distance Charges Multiple Lines Internet Service Internet Type Avg Monthly GB Download Online Security Online Backup Device Protection Plan Premium Tech Support Streaming TV Streaming Movies Streaming Music Unlimited Data Contract Paperless Billing Payment Method Monthly Charge Total Charges Total Refunds Total Extra Data Charges Total Long Distance Charges Total Revenue State City Zip Code Latitude Longitude Satisfaction Score Customer Status Churn Value Churn Category Churn Reason Market Share (% of Population) Customer Share (% of Total Customers) Market Share Bin H3 Index Churn Risk
7 8824-RWFXJ Male 21 Yes No 0 Yes 1 3 Offer E Yes 29.29 No Yes Cable 52 No Yes Yes No No No Yes Yes Month-to-Month Yes Mailed Check 56.15 168.15 0.00 0 87.87 256.02 California Santa Cruz 95062 36.974575 -121.991149 1 Churned 1 Competitor Competitor had better devices 0.0 0.057982 NaN 8428341ffffffff 0.523122
11 5394-SVGJV Male 27 No No 0 No 0 37 NaN Yes 30.72 Yes Yes Fiber Optic 42 No No No Yes Yes Yes Yes Yes Month-to-Month No Bank Withdrawal 98.80 3475.55 0.00 0 1136.64 4612.19 California Sacramento 95838 38.646096 -121.442433 1 Churned 1 Competitor Competitor made better offer 0.0 0.019327 NaN 842832bffffffff 0.509149
12 2357-COQEK Female 79 No No 0 No 0 28 NaN Yes 28.14 Yes Yes Fiber Optic 10 No No Yes Yes Yes Yes No Yes Month-to-Month Yes Bank Withdrawal 103.30 2890.65 0.00 0 787.92 3678.57 California Atherton 94027 37.454924 -122.203168 2 Churned 1 Competitor Competitor made better offer 0.0 0.038655 NaN 8428347ffffffff 0.516793
14 4795-KTRTH Female 68 Yes No 0 Yes 1 5 Offer E Yes 47.28 Yes Yes Fiber Optic 11 No Yes No No No No No No Month-to-Month Yes Bank Withdrawal 81.00 371.65 40.64 10 236.40 577.41 California San Diego 92122 32.857230 -117.209774 1 Churned 1 Competitor Competitor made better offer 0.0 0.057982 NaN 8429a41ffffffff 0.579694
15 2359-KMGLI Male 52 No No 0 No 0 24 Offer C Yes 49.30 Yes Yes Fiber Optic 20 No Yes No No No No No Yes Month-to-Month Yes Bank Withdrawal 80.25 1861.50 0.00 0 1183.20 3044.70 California Running Springs 92382 34.186211 -117.076830 1 Churned 1 Competitor Competitor had better devices 0.0 0.019327 NaN 8429a07ffffffff 0.501785
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
6986 2840-XANRC Male 77 Yes No 0 Yes 1 24 Offer C Yes 16.10 No Yes Cable 12 No No Yes No Yes Yes Yes Yes Month-to-Month Yes Bank Withdrawal 93.15 2231.05 0.00 0 386.40 2617.45 California San Diego 92122 32.857230 -117.209774 2 Churned 1 Competitor Competitor made better offer 0.0 0.057982 NaN 8429a41ffffffff 0.545977
6993 9846-GKXAS Female 53 No No 0 No 0 9 Offer E Yes 1.34 No Yes Fiber Optic 9 No No No No Yes Yes Yes Yes Month-to-Month Yes Bank Withdrawal 90.80 809.75 0.00 0 12.06 821.81 California Burlingame 94010 37.570280 -122.365778 3 Churned 1 Attitude Attitude of support person 0.0 0.038655 NaN 8428343ffffffff 0.500467
7006 7851-WZEKY Female 32 No No 0 No 0 2 Offer E Yes 38.51 Yes Yes Fiber Optic 25 No No No No Yes Yes Yes Yes Month-to-Month Yes Bank Withdrawal 95.15 196.90 0.00 0 77.02 273.92 California Stockton 95219 38.029729 -121.387999 2 Churned 1 Competitor Competitor made better offer 0.0 0.057982 NaN 8428363ffffffff 0.623031
7032 6235-VDHOM Female 77 No No 0 No 0 5 Offer E No 0.00 No Yes DSL 26 No Yes No No No No No Yes Month-to-Month No Bank Withdrawal 28.45 131.05 0.00 0 0.00 131.05 California Riverside 92509 34.004379 -117.447864 2 Churned 1 Dissatisfaction Limited range of services 0.0 0.038655 NaN 8429a01ffffffff 0.508287
7033 5027-QPKTE Male 39 Yes No 0 Yes 1 7 Offer E Yes 14.75 No Yes Fiber Optic 28 No No No No No No No No Month-to-Month Yes Bank Withdrawal 69.35 451.10 0.00 10 103.25 564.35 California Modesto 95350 37.671806 -121.007575 1 Churned 1 Competitor Competitor had better devices 0.0 0.019327 NaN 8428361ffffffff 0.593951

844 rows × 48 columns

6. Predict market share per zip code based on the available columns¶

In [81]:
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import mean_squared_error
In [82]:
customer_df.head()
Out[82]:
Customer ID Gender Age Married Dependents Number of Dependents Referred a Friend Number of Referrals Tenure in Months Offer Home Phone Service Avg Monthly Long Distance Charges Multiple Lines Internet Service Internet Type Avg Monthly GB Download Online Security Online Backup Device Protection Plan Premium Tech Support Streaming TV Streaming Movies Streaming Music Unlimited Data Contract Paperless Billing Payment Method Monthly Charge Total Charges Total Refunds Total Extra Data Charges Total Long Distance Charges Total Revenue State City Zip Code Latitude Longitude Satisfaction Score Customer Status Churn Value Churn Category Churn Reason Market Share (% of Population) Customer Share (% of Total Customers) Market Share Bin H3 Index Churn Risk
0 1608-GMEWB Male 76 No No 0 No 0 45 Offer B Yes 15.65 Yes Yes Fiber Optic 18 No No No No Yes Yes No Yes Two Year Yes Bank Withdrawal 93.9 4200.25 0.0 0 704.25 4904.50 California Stockton 95215 37.946282 -121.139499 4 Stayed 0 NaN NaN 0.0 0.077310 NaN 8428363ffffffff 0.240161
1 2817-LVCPP Female 36 No No 0 No 0 50 NaN Yes 12.62 No No NaN 0 No No No No No No No No Two Year No Credit Card 19.4 1023.95 0.0 0 631.00 1654.95 California Sacramento 95822 38.512569 -121.495184 5 Stayed 0 NaN NaN 0.0 0.077310 NaN 842832bffffffff 0.083341
2 0997-YTLNY Female 59 No Yes 2 No 0 19 Offer D Yes 4.03 No Yes Cable 26 No No No Yes No No No Yes Month-to-Month No Credit Card 48.8 953.65 0.0 0 76.57 1030.22 California Escondido 92029 33.079834 -117.134275 3 Stayed 0 NaN NaN 0.0 0.057982 NaN 8429a47ffffffff 0.184225
3 0526-SXDJP Male 36 Yes No 0 Yes 7 72 Offer A No 0.00 No Yes Cable 17 Yes Yes Yes No No No No Yes Two Year No Bank Withdrawal 42.1 2962.00 0.0 0 0.00 2962.00 California Bell 90201 33.970343 -118.171368 4 Stayed 0 NaN NaN 0.0 0.096637 NaN 8429a57ffffffff 0.118009
4 3466-RITXD Male 34 No No 0 No 0 26 NaN Yes 37.59 Yes Yes Fiber Optic 8 Yes Yes No No Yes No No Yes Month-to-Month Yes Credit Card 92.4 2349.80 0.0 0 977.34 3327.14 California Twin Bridges 95735 38.805481 -120.132870 3 Stayed 0 NaN NaN 16.0 0.077310 10 - 50% 84298d3ffffffff 0.224106
In [83]:
numerical_cols_list = list(numerical_cols) 
zip_features = [col for col in numerical_cols_list if col not in [
    'Zip Code', 
    'Market Share (% of Population)', 
    'Customer Share (% of Total Customers)'
]]
In [84]:
zip_features
Out[84]:
['Age',
 'Number of Dependents',
 'Number of Referrals',
 'Tenure in Months',
 'Avg Monthly Long Distance Charges',
 'Avg Monthly GB Download',
 'Monthly Charge',
 'Total Charges',
 'Total Refunds',
 'Total Extra Data Charges',
 'Total Long Distance Charges',
 'Total Revenue',
 'Satisfaction Score',
 'Churn Value']
In [85]:
zip_code_df = customer_df.groupby('Zip Code')[zip_features].mean().reset_index()
zip_code_df.rename(columns={col: f'avg_{col}' for col in zip_features}, inplace=True)
In [86]:
zip_code_df.head()
Out[86]:
Zip Code avg_Age avg_Number of Dependents avg_Number of Referrals avg_Tenure in Months avg_Avg Monthly Long Distance Charges avg_Avg Monthly GB Download avg_Monthly Charge avg_Total Charges avg_Total Refunds avg_Total Extra Data Charges avg_Total Long Distance Charges avg_Total Revenue avg_Satisfaction Score avg_Churn Value
0 90001 52.25 0.0 0.50 23.75 5.9050 11.25 67.1625 2249.9500 0.000 0.0 327.9925 2577.9425 3.0 0.25
1 90002 50.25 0.0 2.25 35.75 32.4125 7.25 48.2125 1745.0250 11.455 0.0 1014.7350 2748.3050 4.0 0.00
2 90003 46.20 0.6 3.00 14.00 20.3920 14.00 65.5000 1272.8900 0.000 0.0 230.1620 1503.0520 2.6 0.20
3 90004 39.40 0.8 2.40 25.20 18.6380 31.40 51.0900 1564.8300 0.000 8.0 325.9780 1898.8080 3.0 0.40
4 90005 42.25 0.5 2.25 30.00 19.3075 20.25 70.6000 2569.3625 0.000 15.0 449.3675 3033.7300 3.0 0.50
In [87]:
zip_code_df = zip_code_df.merge(market_share_df, on='Zip Code', how='left')
In [88]:
zip_code_df
Out[88]:
Zip Code avg_Age avg_Number of Dependents avg_Number of Referrals avg_Tenure in Months avg_Avg Monthly Long Distance Charges avg_Avg Monthly GB Download avg_Monthly Charge avg_Total Charges avg_Total Refunds avg_Total Extra Data Charges avg_Total Long Distance Charges avg_Total Revenue avg_Satisfaction Score avg_Churn Value Market Share (% of Population) Customer Share (% of Total Customers)
0 90001 52.250000 0.00 0.500000 23.75 5.9050 11.250000 67.162500 2249.950000 0.0000 0.0 327.9925 2577.942500 3.00 0.25 0.000000 0.057982
1 90002 50.250000 0.00 2.250000 35.75 32.4125 7.250000 48.212500 1745.025000 11.4550 0.0 1014.7350 2748.305000 4.00 0.00 0.000000 0.077310
2 90003 46.200000 0.60 3.000000 14.00 20.3920 14.000000 65.500000 1272.890000 0.0000 0.0 230.1620 1503.052000 2.60 0.20 0.000000 0.077310
3 90004 39.400000 0.80 2.400000 25.20 18.6380 31.400000 51.090000 1564.830000 0.0000 8.0 325.9780 1898.808000 3.00 0.40 0.000000 0.057982
4 90005 42.250000 0.50 2.250000 30.00 19.3075 20.250000 70.600000 2569.362500 0.0000 15.0 449.3675 3033.730000 3.00 0.50 0.000000 0.038655
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
1620 96143 49.000000 0.50 2.750000 26.75 22.8800 15.500000 68.387500 2041.350000 0.0000 0.0 555.5375 2596.887500 3.50 0.25 0.000000 0.057982
1621 96145 53.333333 0.00 3.333333 37.00 30.5200 8.666667 89.366667 3791.066667 0.0000 0.0 1199.0900 4990.156667 3.00 0.00 0.000000 0.057982
1622 96146 44.000000 1.25 3.750000 24.25 25.0150 11.250000 61.437500 1431.762500 12.3825 2.5 534.4650 1956.345000 3.75 0.00 0.424628 0.077310
1623 96148 49.000000 0.00 0.000000 30.75 18.0175 22.000000 64.012500 2373.812500 0.0000 0.0 292.8275 2666.640000 2.75 0.50 0.294985 0.038655
1624 96150 50.000000 0.00 0.000000 16.00 5.2000 18.000000 97.150000 1578.650000 0.0000 0.0 144.2500 1722.900000 3.00 1.00 NaN NaN

1625 rows × 17 columns

In [89]:
zip_code_df.isna().sum()
Out[89]:
Zip Code                                  0
avg_Age                                   0
avg_Number of Dependents                  0
avg_Number of Referrals                   0
avg_Tenure in Months                      0
avg_Avg Monthly Long Distance Charges     0
avg_Avg Monthly GB Download               0
avg_Monthly Charge                        0
avg_Total Charges                         0
avg_Total Refunds                         0
avg_Total Extra Data Charges              0
avg_Total Long Distance Charges           0
avg_Total Revenue                         0
avg_Satisfaction Score                    0
avg_Churn Value                           0
Market Share (% of Population)           11
Customer Share (% of Total Customers)    11
dtype: int64
In [90]:
zip_code_df['Market Share (% of Population)'] = zip_code_df['Market Share (% of Population)'].fillna(0)
zip_code_df['Customer Share (% of Total Customers)'] = zip_code_df['Customer Share (% of Total Customers)'].fillna(0)
In [91]:
zip_code_df['Market Share (% of Population)'].describe()
Out[91]:
count    1625.000000
mean        0.318063
std         1.488951
min         0.000000
25%         0.000000
50%         0.000000
75%         0.000000
max        36.363636
Name: Market Share (% of Population), dtype: float64
In [92]:
# Split data into features (X) and target (y)
X = zip_code_df.drop('Market Share (% of Population)', axis=1)
y = zip_code_df['Market Share (% of Population)']

# Split into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
In [93]:
train_df = pd.DataFrame(X_train)
train_df['Market Share (% of Population)'] = y_train
In [94]:
regressor = DecisionTreeRegressor(random_state=42)

# Train the model
regressor.fit(X_train, y_train)
Out[94]:
DecisionTreeRegressor(random_state=42)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
DecisionTreeRegressor(random_state=42)
In [95]:
y_pred = regressor.predict(X_test)

# Calculate Mean Squared Error
mse = mean_squared_error(y_test, y_pred)
print(f'Mean Squared Error: {mse}')
Mean Squared Error: 6.8193489965431136
In [96]:
# save results to a file 
In [97]:
zip_data = zip_code_df.drop(columns=['Market Share (% of Population)'])
In [98]:
market_share_pred = regressor.predict(zip_data)
In [99]:
zip_data['Market Share Pred'] = market_share_pred
In [100]:
zip_data[['Zip Code', 'Market Share Pred']].to_csv('market_share_prediction.csv', index=False)
In [ ]: